package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.zzyl.base.PageResponse;
import com.zzyl.base.ResponseResult;
import com.zzyl.constant.CacheConstants;
import com.zzyl.dto.DeviceDto;
import com.zzyl.dto.DevicePageQueryDto;
import com.zzyl.entity.Device;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DeviceService;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.vo.DeviceVo;
import com.zzyl.vo.ProductVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;

@Service
public class DeviceServiceImpl implements DeviceService {
    @Autowired
    private Client client;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;
    @Autowired
    private DeviceMapper deviceMapper;

    @Override
    public void syncProductList() {
        QueryProductListRequest request = new QueryProductListRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setCurrentPage(1);
        request.setPageSize(100);
        QueryProductListResponse queryProductListResponse = null;
        try {
            queryProductListResponse = client.queryProductList(request);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (queryProductListResponse.getBody().success) {
            List<QueryProductListResponseBody.QueryProductListResponseBodyDataListProductInfo> productInfo = queryProductListResponse.getBody().data.getList().getProductInfo();
            redisTemplate.opsForValue().set(CacheConstants.PRODUCT_LIST, JSONUtil.toJsonStr(productInfo));
        }
    }

    @Override
    public List<ProductVo> allProduct() {
        String s = redisTemplate.opsForValue().get(CacheConstants.PRODUCT_LIST);
        List<ProductVo> list = JSONUtil.toList(s, ProductVo.class);
        return list;
    }

    @Override
    public void registerDevice(DeviceDto deviceDto) {
        //1.通过设备名称查询，是否已经绑定
        String deviceName = deviceDto.getDeviceName();
        int count = deviceMapper.selectByDeviceName(deviceName);
        if (count > 0) {
            throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
        }

        //2.IOT平台注册设备
        RegisterDeviceRequest registerDeviceRequest = deviceDto.getRegisterDeviceRequest();
        registerDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        registerDeviceRequest.setProductKey(deviceDto.getProductKey());
        RegisterDeviceResponse registerDeviceResponse = null;
        try {
            registerDeviceResponse = client.registerDevice(registerDeviceRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        if (!registerDeviceResponse.getBody().success) {
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }

        //3.设置属性
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        device.setIotId(registerDeviceResponse.getBody().data.getIotId());


        //4.获取产品信息
        QueryProductRequest request = new QueryProductRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setProductKey(deviceDto.getProductKey());
        QueryProductResponse queryProductResponse = null;
        try {
            queryProductResponse = client.queryProduct(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_PRODUCT_ERROR);
        }
        if (queryProductResponse.getBody().success) {
            device.setProductName(queryProductResponse.getBody().getData().productName);
        }

        //判断绑定的是否为随身设备
        if (device.getLocationType().equals(0)) {
            device.setPhysicalLocationType(-1);
        }

        //保存设备
        try {
            device.setHaveEntranceGuard(0);
            deviceMapper.insert(device);
        } catch (Exception e) {
            //删除Iot中的设备
            DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
            deleteDeviceRequest.setDeviceName(device.getDeviceName());
            deleteDeviceRequest.setIotId(device.getIotId());
            deleteDeviceRequest.setIotId(aliIoTConfigProperties.getIotInstanceId());
            deleteDeviceRequest.setProductKey(device.getProductKey());
            try {
                client.deleteDevice(deleteDeviceRequest);
            } catch (Exception e1) {
                throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
            }
        }
    }

    @Override
    public PageResponse<DeviceVo> queryPage(DevicePageQueryDto devicePageQueryDto) {
        PageHelper.startPage(devicePageQueryDto.getPageNum(), devicePageQueryDto.getPageSize());
        Page<Device> page = deviceMapper.queryPage(devicePageQueryDto.getDeviceName(), devicePageQueryDto.getLocationType(), devicePageQueryDto.getProductKey());
        return PageResponse.of(page, DeviceVo.class);
    }

    @Override
    public DeviceVo queryDeviceDetail(QueryDeviceDetailRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDeviceDetailResponse response = null;
        try {
            response = client.queryDeviceDetail(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        if (!response.getBody().success) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }


        //查询数据库的数据
        DeviceVo deviceVo = deviceMapper.selectByIotId(response.getBody().getData().getIotId());
        QueryDeviceDetailResponseBody.QueryDeviceDetailResponseBodyData data = response.getBody().getData();
        BeanUtil.copyProperties(data, deviceVo, CopyOptions.create().ignoreNullValue());
        return deviceVo;
    }

    @Override
    public ResponseResult queryDevicePropertyStatus(QueryDevicePropertyStatusRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDevicePropertyStatusResponse response;
        try {
            response = client.queryDevicePropertyStatus(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_PROPERTY_STATUS_ERROR);
        }
        return ResponseResult.success(response.getBody().getData());
    }

    @Override
    public HashMap<String, String> queryThingModelPublished(QueryThingModelPublishedRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryThingModelPublishedResponse queryThingModelPublishedResponse = null;
        try {
            queryThingModelPublishedResponse = client.queryThingModelPublished(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        if (!queryThingModelPublishedResponse.getBody().success) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        String thingModelJson = queryThingModelPublishedResponse.getBody().getData().getThingModelJson();
        HashMap<String, String> map = new HashMap<>();
        map.put("thingModelJson", thingModelJson);
        return map;
    }

    @Override
    public void updateDevice(DeviceDto deviceDto) {
        //先查看数据库是否存在该设备
        Device devicedata = deviceMapper.selectDeviceById(deviceDto.getId());
        if (ObjectUtil.isEmpty(devicedata)) {
            throw new BaseException(BasicEnum.DEVICE_NOT_EXIST);
        }

        BatchUpdateDeviceNicknameRequest request = new BatchUpdateDeviceNicknameRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo bean = BeanUtil.toBean(deviceDto, BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo.class);
        request.setDeviceNicknameInfo(Lists.newArrayList(bean));

        BatchUpdateDeviceNicknameResponse response;
        try {
            response = client.batchUpdateDeviceNickname(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_BATCH_UPDATE_DEVICE_ERROR);
        }
        if (ObjectUtil.notEqual(Boolean.TRUE, response.getBody().getSuccess())) {
            throw new BaseException(BasicEnum.IOT_BATCH_UPDATE_DEVICE_ERROR);
        }


        Device device = BeanUtil.toBean(deviceDto, Device.class);

        //如果修改成随身设备  改成-1
        if (device.getLocationType().equals(0)) {
            device.setPhysicalLocationType(-1);
        }

        //数据库修改
        try {
            deviceMapper.update(device);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.RE_SELECT_PRODUCT);
        }
    }

    @Override
    public void deleteDevice(DeleteDeviceRequest deleteDeviceRequest) {
        deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        DeleteDeviceResponse response = null;
        try {
            response = client.deleteDevice(deleteDeviceRequest);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }
        if (!response.getBody().success) {
            throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }
        deviceMapper.deleteByIotId(deleteDeviceRequest.getIotId());
    }

}
